
#include "midi.h"

void midiCallback(double deltatime, std::vector<unsigned char> *message, void *userData)
{
    ((Midi*) userData)->procesarMensaje(deltatime, message);
}

Midi::Midi(QObject *parent) :  QObject(parent)
{
    try {
        midiIn = new RtMidiIn();
    } catch (RtError &error) {
    // Handle the exception here
        midiIn = NULL;
        error.printMessage();
    }
}

QStringList Midi::getListaNombresPuertosEntrada()
{
    QStringList listaNombresPuertosEntrada;

    unsigned int numeroPuertos = midiIn->getPortCount();
    std::string nombrePuerto;
    for (unsigned int i = 0; i < numeroPuertos; i++) {
        try {
          nombrePuerto = midiIn->getPortName(i);
        } catch (RtError &error) {
          //error.printMessage();
          continue;
        }
        listaNombresPuertosEntrada.append(QString::fromStdString(nombrePuerto));
    }
    return listaNombresPuertosEntrada;
}

Midi::~Midi()
{
    if (midiIn != NULL) {
        delete midiIn;
    }
}

bool Midi::abrirPuerto(int numeroPuerto)
{
    if (midiIn == NULL) {
        return false;
    }
    try {
        midiIn->openPort(numeroPuerto);
        midiIn->setCallback(&midiCallback, this);
    } catch (RtError &error) {
        return false;
    }


    return true;
}

bool Midi::abrirPuerto(const QString& nombrePuerto)
{
    QStringList listaNombres = getListaNombresPuertosEntrada();

    int numeroPuerto = listaNombres.indexOf(nombrePuerto);
    if (numeroPuerto < 0) {
        return false;
    }
    return abrirPuerto(numeroPuerto);
}

bool Midi::cerrarPuerto()
{
    if (midiIn == NULL) {
        return false;
    }
	try {
		midiIn->closePort();
	} catch (RtError &error) {
        return false;
    }
    return true;
}


void Midi::procesarMensaje(double deltatime, std::vector<unsigned char> *message)
{
    MensajeMidi mensajeMidi;
    mensajeMidi.asignarDatos(message, deltatime);

    emit mensajeRecibido(mensajeMidi);
}

